#pragma region Include

#include <Windows.h>
#include <conio.h>
#include <stdio.h>
#include <io.h>
#include <iostream>
#include <locale.h>

#include "net.h"
#include "parser.h"
#include "response.h"
#include "other.h"
#include "MIME-types.h"
#include "charset_codes.h"
#include "control.h"
#include "file.h"
#pragma endregion Include

#define ROOT_DOCUMENT	"d:\\"

HANDLE th = 0;
HANDLE th_creating = NULL;
HANDLE ev_created = NULL;

FILE *fp; 

CRITICAL_SECTION cs;

void thread_routine(LPVOID params)
{
	printf("thread: wait \n");
	//WaitForSingleObject(th_creating, INFINITE);
	
	printf("thread: go \n");

	//ReleaseMutex(th_creating);
	//printf("%d Release mutex \n", th);

	CSrvCon *p_srv = (CSrvCon *)params;
	CControl *control;
	char *response = NULL;
	long response_size = 0;
	char buf[MAX_BUF];
	SOCKET clt_s = p_srv->get_clt_socket();

	printf("%d thread start: %d\n", th, clt_s);
	//fprintf(fp, "thread start: %d\n", clt_s);

	control = new CControl;

	memset(buf, 0 , MAX_BUF);

	EnterCriticalSection(&cs);
	printf("Enter CS 1 %d\n", th);

	p_srv->recv_data_from(clt_s, buf, MAX_BUF);

	printf("<------------------------------------\n%s\n", buf);

	//fprintf(fp, "<---\n%s\n", buf);
	LeaveCriticalSection(&cs);
	printf("%d Leave CS 1\n", th);

	if(strlen(buf) == 0)
	{
		printf("%d buf = 0\n", th);
		getch();
		p_srv->shutdown_client(clt_s);

		delete control;

		SetEvent(ev_created);
		
		ExitThread(1);
	}

	response = control->get_response(buf);
	response_size = control->get_response_size();

	EnterCriticalSection(&cs);
	printf("%d Enter CS 2\n", th);

	if(response)
	{
		p_srv->send_data_to(clt_s, response, response_size - 1);

		printf("%d --->send\n", th);
//		fprintf(fp, "--->send \n%s\n", response);
	}

	delete control;

	printf("%d thread stop: %d\n", th, clt_s);
	//fprintf(fp, "thread stop: %d\n", clt_s);
	p_srv->shutdown_client(clt_s);

	LeaveCriticalSection(&cs);
	printf("%d Leave CS 2\n", th);

	SetEvent(ev_created);
	
	ExitThread(0);
}

void main()
{
	setlocale(LC_ALL, "Russian");

	/*CFile files;
	list<CFile::RECORD> list_files;
	list<CFile::RECORD>::iterator it;

	list<string> list_drives;
	list<string>::iterator it_d;

	list_drives = files.GetListDrives();
	for(it_d = list_drives.begin(); it_d != list_drives.end(); it_d++)
	{
		cout<<(*it_d)<<"\n";
	}

	files.SetCurPath("D:");

	cout<<"\n";
	cout<<files.GetCurPath()<<"\n";
	cout<<"\n";

	list_files = files.GetListFiles();
	for(it = list_files.begin(); it!=list_files.end(); it++)
	{
		if((*it).f_dir)
			cout<<(*it).file_name<<" "<<"D\n";
		else
			cout<<(*it).file_name<<"\n";
	}
	
	cout<<"\n"<<files.GenHtmlListFilesPage("127.0.0.1:5000")<<"\n";

	files.SaveHtmlListFilesPageToFile();
	*/
	//fp = fopen("d:\\1.log","w");
	/*NOTIFYICONDATA ni;

	ni.cbSize = sizeof(NOTIFYICONDATA);
	ni.hWnd = NULL;
	
	Shell_NotifyIcon(NIM_ADD, &ni);
	*/
	CSrvCon srv;
	
	//srv.set_address("192.168.1.2");
	srv.set_address("10.30.198.234");
	//srv.set_address("127.0.0.1");
	srv.open_port();

	printf("start\n");
	
	char *response = NULL;
	long response_size = 0;

	DWORD result = 0;
	int count = 0;

	//th_creating = CreateMutex(NULL, false, "th_created");
	ev_created = CreateEvent(NULL, true, true, "cr");

	if (!InitializeCriticalSectionAndSpinCount(&cs, 
        0x80000400) ) 
        return;

	while(1)
	{
		printf("srv1: wait\n");
		result = WaitForSingleObject(ev_created, INFINITE);
		printf("srv1: go\n");

		printf("waiting connection\n");
		srv.accept_connection();
		printf("connection accept: %d\n", count);
		//fprintf(fp, "connection accept: %d\n", i);

		if(result == WAIT_OBJECT_0)
		{
			ResetEvent(ev_created);

			th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_routine,
					(LPVOID)&srv, 0, NULL);
			if(th == NULL)
				break;

			printf("created_thread: %d\n", th);
	//		Sleep(1000);
		}

		//ReleaseMutex(th_creating);
		//printf("srv1: release \n");
		/*printf("srv2: wait\n");
		result = WaitForSingleObject(th_creating, INFINITE);
		printf("srv2: go\n");*/
		//Sleep(1000);

		count++;
	}


	DeleteCriticalSection(&cs);

	getch();

	srv.close_port();
	//CloseHandle(th_creating);
	CloseHandle(ev_created);

	printf("end\n");

	getch();
}